<template>
  <div id="app">
    <div class="loading" ref="loading" :style="{
      top:`${loadingTop}px`
    }">
      <div class="loading-item" :style="{
        display:loadingItemDisplay
      }"></div>
    </div>
    <div class="play-mask" :style="{
      display:playMaskDisplay
      }">
      <PlayAudioButton
        :style="{
        transform:`translate(${translateX}px,${translateY}px) scale(${scale})`,
        transformOrigin:'center',
      }"
        :can-toggle="false"
        @click="loadMusic"
      />
    </div>
    <div
      ref="bkgnd"
      class="bkgnd"
      :style="{
      backgroundImage:bkgnd,
      filter:`brightness(${brightness})`
    }"
    ></div>
    <TitleBar :title="title" style="visibility:visible;z-index:4;position:absolute;width:100%" />
    <div :style="{height:'100%',opacity:vis}">
      <div class="content">
        <div class="anime-info">
          <div class="desc">{{desc}}</div>
          <div class="desc-title">{{descTitle?'——《'+descTitle+'》':''}}</div>
        </div>
        <div class="controls">
          <div class="buttons">
            <PlayAudioButton
              :style="{
              visibility:playBtnVisibility
            }"
              ref="playBtn"
              @click="handlePlayPause"
            />
            <NextAudioButton />
          </div>
          <div class="time">{{hasTime?`${currentTime} / ${totalTime}`:''}}</div>
        </div>
      </div>

      <div class="sliders" :style="{opacity:vis}">
        <div class="s">
          <span>音调</span>
          <Slider
            @value-changed="handlePitchChanged"
            :selection="pitchSelection"
            :init-selection="12"
            :filter="(v)=>{
          if(v>0){
            return '+'+v
          }
          return ''+v
          }"
          />
        </div>
        <div class="s">
          <span>速率</span>
          <Slider
            @value-changed="handleTempoChanged"
            :selection="tempoSelection"
            :init-selection="5"
            :filter="(v)=>{
          return v+'×'
          }"
          />
        </div>
        <div class="s">
          <span>音量</span>
          <Slider
            @value-changed="handleVolumeChanged"
            :selection="volumeSelection"
            :init-selection="101"
          />
        </div>
      </div>
      <ProgressBar :style="{opacity:vis}" />
    </div>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import TitleBar from "@/components/TitleBar.vue";
import PlayAudioButton from "@/components/PlayAudioButton.vue";
import NextAudioButton from "@/components/NextAudioButton.vue";
import Slider from "@/components/Slider.vue";
import ProgressBar from "@/components/ProgressBar.vue";
import * as d3 from "d3";

@Component({
  components: {
    TitleBar,
    PlayAudioButton,
    NextAudioButton,
    Slider,
    ProgressBar
  }
})
export default class App extends Vue {
  private pitchSelection: number[] = [...Array(25)].map((_, i) => i - 12);
  private tempoSelection: number[] = [...Array(16)].map((_, i) => (i + 5) / 10);
  private volumeSelection: number[] = [...Array(101)].map((_, i) => i);
  private bkgnd: string = "linear-gradient(to right,gray,darkgray,gray)";
  private title: string = "ACG歌曲播放器（仮）";
  private desc: string = "";
  private descTitle: string = "";
  private totalTime: string = "";
  private currentTime: string = "";
  private hasTime: boolean = false;
  private playBtnVisibility: string = "hidden";
  private vis: number = 0;
  private playMaskDisplay: string = "block";
  private loadingItemDisplay: string = "none";
  private brightness: number = 1;
  private translateX: number = 260;
  private translateY: number = 110;
  private scale: number = 2.5;
  private loadingTop: number = -350;
  private progress: number = 0;
  private handlePlayPause() {
    window.ipcRenderer.send("play-or-pause", this.$store.state.pause);
  }
  private handleVolumeChanged(idx) {
    window.ipcRenderer.send("volume-changed", this.volumeSelection[idx]);
  }
  private handlePitchChanged(idx) {
    window.ipcRenderer.send("pitch-changed", this.pitchSelection[idx]);
  }
  private handleTempoChanged(idx) {
    window.ipcRenderer.send("tempo-changed", this.tempoSelection[idx]);
  }
  public mounted() {
    window.ipcRenderer.on("random-music-data", this.getRandomMusicData);
    window.ipcRenderer.on("update-time", this.updateTime);
    // setTimeout(() => {
    // this.vis = "visible";
    // this.playMaskDisplay = "none";
    // this.playBtnVisibility = "visible";
    // }, 5000);
  }
  private updateTime(event, obj: [string, string]) {
    this.currentTime = obj[0];
    this.totalTime = obj[1];
    const convert = v => {
      const [a1, a2] = v.split(":");
      return +a1 * 60 + +a2;
    };
    const progress = convert(this.currentTime) / convert(this.totalTime);
    this.$store.commit("SET_PROGRESS", progress);
    this.$store.commit("SET_DURATION", convert(this.totalTime));
  }
  private getRandomMusicData(event, obj: AnimeObject) {
    console.log(obj);
    this.hasTime = true;
    this.loadingItemDisplay = "none";
    this.setBkgnd(obj.anime_info.logo);
    this.setTitle(obj.title);
    this.setDesc(obj.anime_info.desc);
    this.setDescTitle(obj.anime_info.title);
    this.hideLoad().then(() => {
      this.vis = "visible";
      this.playMaskDisplay = "none";
      this.playBtnVisibility = "visible";
      (<Element>this.$refs.playBtn.$el).click();
    });
  }
  private setBkgnd(url) {
    this.bkgnd = `url(${url})`;
    this.brightness = 0.5;
  }
  private setTitle(title) {
    this.title = title;
  }
  private setDesc(desc) {
    this.desc = desc;
  }
  private setDescTitle(descTitle) {
    this.descTitle = descTitle;
  }
  private makeTitle(name, singer) {
    return `${name} - ${singer}`;
  }
  private displayLoad() {
    return new Promise(resolve => {
      d3.transition()
        .duration(800)
        .ease(d3.easeBounceOut)
        .tween("loadingStart", () => {
          const i10r = d3.interpolateNumber(this.loadingTop, 0);
          return t => {
            this.loadingTop = i10r(t);
          };
        })
        .end()
        .then(resolve);
    });
  }
  private hideLoad() {
    return new Promise(resolve => {
      d3.transition()
        .duration(400)
        .ease(d3.easeLinear)
        .tween("loadingEnd", () => {
          const i10r = d3.interpolateNumber(this.loadingTop, -350);
          const i10r2 = d3.interpolateNumber(this.translateX, 413);
          const i10r3 = d3.interpolateNumber(this.translateY, 56);
          const i10r4 = d3.interpolateNumber(this.scale, 1);
          const i10r5 = d3.interpolateNumber(this.vis, 1);
          return t => {
            this.loadingTop = i10r(t);
            this.translateX = i10r2(t);
            this.translateY = i10r3(t);
            this.scale = i10r4(t);
            this.vis = i10r5(t);
          };
        })
        .end()
        .then(resolve)
        .catch(() => {});
    });
  }
  private async loadMusic() {
    await this.displayLoad();
    this.loadingItemDisplay = "block";
    window.ipcRenderer.send("init-load");
  }
}
</script>

<style lang="scss">
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: white;
  user-select: none;
  height: 100%;
  .loading {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 3;
    border-radius: 0 0 6px 6px;
    background: black;
    opacity: 0.6;
    display: flex;
    align-items: center;
    justify-content: center;
    @keyframes rotate {
      from {
        transform: rotate(0);
      }
      to {
        transform: rotate(360deg);
      }
    }
    &-item {
      margin-top: 10px;
      width: 200px;
      height: 200px;
      border-radius: 50%;
      border: 5px solid lightgray;
      border-right: 0;
      animation: rotate 1s linear infinite;
    }
  }
  .play-mask {
    position: absolute;
    width: 100%;
    height: calc(100% - 30px);
    z-index: 2;
    top: 30px;
    border-radius: 0 0 6px 6px;
  }
  .bkgnd {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: -1;
    opacity: 0.95;
    border-radius: 6px;
    background-size: cover;
  }
  .content {
    position: absolute;
    top: 30px;
    bottom: 80px;
    width: 100%;
    display: flex;
    flex-flow: row nowrap;

    .anime-info {
      flex: 1;
      display: flex;
      flex-flow: column nowrap;
      margin: 20px;
      opacity: 0.85;

      .desc {
        flex: 1;
        text-indent: 2em;
        line-height: 28px;
        font-size: 14px;
        overflow: scroll;
        background-color: rgba($color: #000000, $alpha: 0.5);
        mask-image: linear-gradient(to bottom, black 90%, transparent);
        &::-webkit-scrollbar {
          width: 0;
        }
      }
      .desc-title {
        flex-basis: 30px;
        text-align: right;
        font-size: 14px;
        padding-top: 10px;
      }
    }
    .controls {
      flex-basis: 200px;
      display: flex;
      flex-flow: column nowrap;
      justify-content: center;
      .buttons {
        display: flex;
        justify-content: space-evenly;
      }
      .time {
        margin-top: 20px;
        text-align: center;
        font-size: 24px;
        height: 30px;
      }
    }
  }
}
.sliders {
  display: flex;
  flex-flow: row nowrap;
  position: absolute;
  bottom: 30px;
  height: 50px;
  width: 100%;
  .s {
    flex: 1;
    span {
      font-size: 14px;
      line-height: 30px;
      vertical-align: top;
      padding-left: 10px;
    }
  }
}
</style>
